home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP11.ZIP / CHAP11 / POLYLINE / POLYWIN.CPP < prev    next >
C/C++ Source or Header  |  1993-06-22  |  12KB  |  428 lines

  1. /*
  2.  * POLYWIN.CPP
  3.  *
  4.  * Window procedure for the polyline drawing window and support functions.
  5.  * This window is not complicated.  On creation it allocates a block of
  6.  * memory for a POLYLINEDATA structure that contains 20 POINTs.  We do not
  7.  * attempt to reallocate this array at all just to maintain simplicity.
  8.  *
  9.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Software Design Engineer
  12.  * Microsoft Systems Developer Relations
  13.  *
  14.  * Internet  :  kraigb@microsoft.com
  15.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  16.  */
  17.  
  18.  
  19.  
  20. #include <windows.h>
  21. #include <ole2.h>
  22. #include "polyline.h"
  23.  
  24.  
  25.  
  26.  
  27. /*
  28.  * PolylineWndProc
  29.  *
  30.  * Purpose:
  31.  *  Window procedure for the polyline drawing window.
  32.  */
  33.  
  34. LRESULT __export FAR PASCAL PolylineWndProc(HWND hWnd, UINT iMsg
  35.     , WPARAM wParam, LPARAM lParam)
  36.     {
  37.     LPCPolyline     ppl;
  38.     PAINTSTRUCT     ps;
  39.     HDC             hDC;
  40.     POINT           pt;
  41.     RECT            rc;
  42.  
  43.     ppl=(LPCPolyline)GetWindowLong(hWnd, PLWL_STRUCTURE);
  44.  
  45.     switch (iMsg)
  46.         {
  47.         case WM_CREATE:
  48.             ppl=(LPCPolyline)((LPCREATESTRUCT)lParam)->lpCreateParams;
  49.             SetWindowLong(hWnd, PLWL_STRUCTURE, (LONG)ppl);
  50.  
  51.             //CHAPTER11MOD
  52.             //Moved call to New() to Init.
  53.             ppl->m_hWnd=hWnd;
  54.             //End CHAPTER11MOD
  55.             break;
  56.  
  57.  
  58.         case WM_PAINT:
  59.             hDC=BeginPaint(hWnd, &ps);
  60.             GetClientRect(hWnd, &rc);
  61.             ppl->Draw(hDC, FALSE, TRUE, &rc, NULL);
  62.             EndPaint(hWnd, &ps);
  63.             break;
  64.  
  65.  
  66.         case WM_LBUTTONDOWN:
  67.             //Stop if we are already at the limit.
  68.             if (CPOLYLINEPOINTS==ppl->m_pl.cPoints)
  69.                 {
  70.                 MessageBeep(0);
  71.                 break;
  72.                 }
  73.  
  74.             //Convert the points into 0-32767 range
  75.             GetClientRect(hWnd, &rc);
  76.             pt=MAKEPOINT(lParam);
  77.             ppl->PointScale(&rc, &pt, FALSE);
  78.  
  79.             ppl->m_pl.rgpt[ppl->m_pl.cPoints++]=pt;
  80.  
  81.             //Draw the lines to this new point only.
  82.             hDC=GetDC(hWnd);
  83.             ppl->Draw(hDC, FALSE, FALSE, &rc, NULL);
  84.             ReleaseDC(hWnd, hDC);
  85.  
  86.             if (NULL!=ppl->m_pAdv)
  87.                 ppl->m_pAdv->OnPointChange();
  88.  
  89.             //CHAPTER11MOD
  90.             //Notifications necessary to support compound documents.
  91.             ppl->SendAdvise(OBJECTCODE_DATACHANGED);
  92.             //End CHAPTER11MOD
  93.             break;
  94.  
  95.  
  96.         default:
  97.             return DefWindowProc(hWnd, iMsg, wParam, lParam);
  98.         }
  99.  
  100.     return 0L;
  101.     }
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109. /*
  110.  * CPolyline::Draw
  111.  *
  112.  * Purpose:
  113.  *  Paints the current line in the polyline window.
  114.  *
  115.  * Parameters:
  116.  *  hDC             HDC to draw on, could be a metafile or printer DC.
  117.  *  fMetafile       BOOL indicating if hDC is a metafile or not, so we
  118.  *                  can avoid operations that RIP.
  119.  *  fEntire         BOOL indicating if we should draw the entire figure
  120.  *                  or not.
  121.  *  pRect           LPRECT defining the bounds on hDC in which to draw.
  122.  *  ppl             LPPOLYLINEDATA to draw.  If NULL, we use the current.
  123.  *
  124.  * Return Value:
  125.  *  None
  126.  */
  127.  
  128. void CPolyline::Draw(HDC hDC, BOOL fMetafile, BOOL fEntire, LPRECT pRect
  129.     , LPPOLYLINEDATA ppl)
  130.     {
  131.     //CHAPTER11MOD
  132.     HBRUSH          hBrush;
  133.     HPEN            hPen;
  134.     HGDIOBJ         hObj1, hObj2;
  135.     UINT            i, j;
  136.     POINT           pt[2];
  137.     int             nDC;
  138.  
  139.     if (NULL==ppl)
  140.         ppl=&m_pl;
  141.  
  142.     nDC=SaveDC(hDC);
  143.  
  144.     //Printer and frozen differences handled in IViewObject::Draw
  145.  
  146.     hPen=CreatePen(ppl->iLineStyle, 1, ppl->rgbLine);
  147.     hObj1=SelectObject(hDC, hPen);
  148.  
  149.     hBrush=CreateSolidBrush(ppl->rgbBackground);
  150.     hObj2=SelectObject(hDC, hBrush);
  151.     SetBkColor(hDC, ppl->rgbBackground);
  152.  
  153.     /*
  154.      * Either draw the entire figure or just a single point.  The
  155.      * entire figure also includes erasing the background completely,
  156.      * since hDC may be a metafile DC.  Drawing a single point just
  157.      * updates the figure for that new point.
  158.      */
  159.     if (fEntire || 0==ppl->cPoints)
  160.         {
  161.         //Erase the background for bitmaps and metafiles.
  162.         SelectObject(hDC, GetStockObject(NULL_PEN));
  163.         Rectangle(hDC, pRect->left, pRect->top, pRect->right+1, pRect->bottom+1);
  164.         SelectObject(hDC, hPen);
  165.  
  166.         /*
  167.          * If we are drawing the entire figure, then loop through each
  168.          * point drawing a line to each successive point.
  169.          */
  170.  
  171.         for (i=0; i < ppl->cPoints; i++)
  172.             {
  173.             for (j=i; j < ppl->cPoints; j++)
  174.                 {
  175.                 pt[0]=ppl->rgpt[i];
  176.                 pt[1]=ppl->rgpt[j];
  177.                 PointScale(pRect, &pt[0], TRUE);
  178.                 PointScale(pRect, &pt[1], TRUE);
  179.                 MoveTo(hDC, pt[0].x, pt[0].y);
  180.                 LineTo(hDC, pt[1].x, pt[1].y);
  181.                 }
  182.             }
  183.         }
  184.     else
  185.         {
  186.         /*
  187.          * If we are only drawing the last point, just cycle once
  188.          * through previous points.
  189.          */
  190.  
  191.         //Get the last point entered in the array.
  192.         j=ppl->cPoints-1;
  193.         pt[0]=ppl->rgpt[j];
  194.         PointScale(pRect, &pt[0], TRUE);
  195.  
  196.         for (i=0; i < j; i++)
  197.             {
  198.             pt[1]=ppl->rgpt[i];
  199.             PointScale(pRect, &pt[1], TRUE);
  200.  
  201.             MoveTo(hDC, pt[0].x, pt[0].y);
  202.             LineTo(hDC, pt[1].x, pt[1].y);
  203.             }
  204.         }
  205.  
  206.     //If we only had one point, draw a dot to indicate it's position.
  207.     if (1==ppl->cPoints)
  208.         {
  209.         pt[0]=ppl->rgpt[0];
  210.         PointScale(pRect, &pt[0], TRUE);
  211.         SetPixel(hDC, pt[0].x, pt[0].y, ppl->rgbLine);
  212.         }
  213.  
  214.     SelectObject(hDC, hObj1);
  215.     SelectObject(hDC, hObj2);
  216.     DeleteObject(hBrush);
  217.     DeleteObject(hPen);
  218.  
  219.     RestoreDC(hDC, nDC);
  220.     return;
  221.     //End CHAPTER11MOD
  222.     }
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230. /*
  231.  * CPolyline::PointScale
  232.  *
  233.  * Purpose:
  234.  *  Scales a point to or from a relative window coordinate to a 0-32767
  235.  *  coordinate.
  236.  *
  237.  * Parameters:
  238.  *  pRect           LPRECT of the window.
  239.  *  ppt             LPPOINT to convert
  240.  *  fScaleToWindow  BOOL indicating direction of scaling.
  241.  *
  242.  * Return Value:
  243.  *  None
  244.  */
  245.  
  246. void CPolyline::PointScale(LPRECT pRect, LPPOINT ppt, BOOL fScaleToWindow)
  247.     {
  248.     DWORD   cx, cy;
  249.  
  250.     //Window size
  251.     cx=(DWORD)(pRect->right-pRect->left);
  252.     cy=(DWORD)(pRect->bottom-pRect->top);
  253.  
  254.     //Prevent crashes
  255.     if (0L==cx) cx=1;
  256.     if (0L==cy) cy=1;
  257.  
  258.     //Must use DWORD to insure proper scaling.
  259.     //CHAPTER11MOD
  260.     /*
  261.      * As an in-proc server we may not have a rectangle where the
  262.      * top left was (0,0) which was always true when we drew to
  263.      * a Polyline window.  But this may be a container's hDC in which
  264.      * case we'd better place the points in the container's rectangle.
  265.      * That is, we have to add/subtract pRect->left and ->top in
  266.      * these calculations.
  267.      */
  268.  
  269.     if (fScaleToWindow)
  270.         {
  271.         ppt->x=pRect->left+(UINT)(((DWORD)ppt->x*cx) >> 15);
  272.         ppt->y=pRect->top+(UINT)(((DWORD)ppt->y*cy)  >> 15);
  273.         }
  274.     else
  275.         {
  276.         ppt->x=(UINT)(((DWORD)(ppt->x - pRect->left) << 15)/cx);
  277.         ppt->y=(UINT)(((DWORD)(ppt->y - pRect->top)  << 15)/cy);
  278.         }
  279.     //End CHAPTER11MOD
  280.  
  281.     return;
  282.     }
  283.  
  284.  
  285.  
  286. //CHAPTER11MOD
  287. /*
  288.  * PolyDlgProc
  289.  *
  290.  * Purpose:
  291.  *  Dialog procedure for a window in which to display the Polyline
  292.  *  for editing.  This pretty much handles all editing functionality
  293.  *  for the embedded object.
  294.  */
  295.  
  296. BOOL __export FAR PASCAL PolyDlgProc(HWND hDlg, UINT iMsg
  297.     , WPARAM wParam, LPARAM lParam)
  298.     {
  299.     LPCPolyline     ppl=NULL;
  300.     WORD            w1, w2;
  301.     HWND            hWnd;
  302.     RECT            rc;
  303.     POINT           pt;
  304.     UINT            uID, uTemp;
  305.     UINT            cx, cy;
  306.  
  307.     w1=(WORD)GetProp(hDlg, PROP_SELECTOR);
  308.     w2=(WORD)GetProp(hDlg, PROP_OFFSET);
  309.  
  310.     ppl=(LPCPolyline)MAKELP(w1, w2);
  311.  
  312.     switch (iMsg)
  313.         {
  314.         case WM_INITDIALOG:
  315.             ppl=(LPCPolyline)lParam;
  316.             ppl->m_hDlg=hDlg;
  317.  
  318.             SetProp(hDlg, PROP_SELECTOR, (HANDLE)SELECTOROF(ppl));
  319.             SetProp(hDlg, PROP_OFFSET,   (HANDLE)OFFSETOF(ppl));
  320.  
  321.             //Center the dialog on the screen
  322.             cx=GetSystemMetrics(SM_CXSCREEN);
  323.             cy=GetSystemMetrics(SM_CYSCREEN);
  324.             GetWindowRect(hDlg, &rc);
  325.             SetWindowPos(hDlg, NULL, (cx-(rc.right-rc.left))/2
  326.                 , (cy-(rc.bottom-rc.top))/2, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
  327.  
  328.             //Create the Polyline to exactly cover the static rectangle.
  329.             hWnd=GetDlgItem(hDlg, ID_POLYLINERECT);
  330.             GetWindowRect(hWnd, &rc);
  331.             SETPOINT(pt, rc.left, rc.top);
  332.             ScreenToClient(hDlg, &pt);
  333.  
  334.             //Set the polyline just within the black frame
  335.             SetRect(&rc, pt.x, pt.y, pt.x+(rc.right-rc.left)
  336.                 , pt.y+(rc.bottom-rc.top));
  337.             InflateRect(&rc, -1, -1);
  338.  
  339.             //Try to create the window.
  340.             ppl->m_pIPolyline->Init(hDlg, &rc, WS_CHILD | WS_VISIBLE, ID_POLYLINE);
  341.  
  342.             //Set the initial line style radiobutton.
  343.             ppl->m_pIPolyline->LineStyleGet(&uTemp);
  344.             CheckRadioButton(hDlg, ID_LINESOLID, ID_LINEDASHDOTDOT
  345.                 , uTemp+ID_LINEMIN);
  346.  
  347.             ppl->SendAdvise(OBJECTCODE_SHOWOBJECT);
  348.             ppl->SendAdvise(OBJECTCODE_SHOWWINDOW);
  349.             return TRUE;
  350.  
  351.  
  352.         case WM_COMMAND:
  353.             uID=LOWORD(wParam);
  354.  
  355.             switch (uID)
  356.                 {
  357.                 case IDOK:
  358.                     RemoveProp(hDlg, PROP_SELECTOR);
  359.                     RemoveProp(hDlg, PROP_OFFSET);
  360.  
  361.                     if (NULL!=ppl)
  362.                         {
  363.                         ppl->SendAdvise(OBJECTCODE_HIDEWINDOW);
  364.                         ppl->SendAdvise(OBJECTCODE_CLOSED);
  365.                         ppl->m_hDlg=NULL;
  366.                         }
  367.  
  368.                     EndDialog(hDlg, TRUE);
  369.                     break;
  370.  
  371.                 case ID_UNDO:
  372.                     if (NULL!=ppl)
  373.                         ppl->m_pIPolyline->Undo();
  374.                     break;
  375.  
  376.                 case ID_COLORLINE:
  377.                 case ID_COLORBACK:
  378.                     if (NULL!=ppl)
  379.                         {
  380.                         UINT            i;
  381.                         COLORREF        rgColors[16];
  382.                         CHOOSECOLOR     cc;
  383.  
  384.                         //Invoke the color chooser for either color
  385.                         uTemp=(ID_COLORBACK==uID)
  386.                             ? POLYLINECOLOR_BACKGROUND : POLYLINECOLOR_LINE;
  387.  
  388.                         for (i=0; i<16; i++)
  389.                             rgColors[i]=RGB(0, 0, i*16);
  390.  
  391.                         _fmemset(&cc, 0, sizeof(CHOOSECOLOR));
  392.                         cc.lStructSize=sizeof(CHOOSECOLOR);
  393.                         cc.lpCustColors=rgColors;
  394.                         cc.hwndOwner=hDlg;
  395.                         cc.Flags=CC_RGBINIT;
  396.                         ppl->m_pIPolyline->ColorGet(uTemp, &cc.rgbResult);
  397.  
  398.                         if (ChooseColor(&cc))
  399.                             {
  400.                             //rgColor is just some COLORREF pointer
  401.                             ppl->m_pIPolyline->ColorSet(uTemp, cc.rgbResult
  402.                                 , rgColors);
  403.                             }
  404.                         }
  405.                     break;
  406.  
  407.                 case ID_LINESOLID:
  408.                 case ID_LINEDASH:
  409.                 case ID_LINEDOT:
  410.                 case ID_LINEDASHDOT:
  411.                 case ID_LINEDASHDOTDOT:
  412.                     if (NULL!=ppl)
  413.                         ppl->m_pIPolyline->LineStyleSet(uID-ID_LINEMIN, &uTemp);
  414.  
  415.                     break;
  416.                 }
  417.             break;
  418.  
  419.         case WM_CLOSE:
  420.             //Close just like we hit the "Close" button.
  421.             SendCommand(hDlg, IDOK, 0, 0);
  422.             break;
  423.         }
  424.     return FALSE;
  425.     }
  426.  
  427. //End CHAPTER11MOD
  428.